//
// Created by 17775 on 2024/6/17.
//

#ifndef RAYCI_RAYCIMAINWINDOW_H
#define RAYCI_RAYCIMAINWINDOW_H

#include "BeamProfiler.h"
#include "RayCi/LiveMode.h"
#include "LiveMode/livemode_2d_view.h"
#include "LiveMode/livemode_options.h"
#include "Common/beamresults.h"
#include "RayCi/LiveMode_PowerProfiles.h"
#include "LiveMode/livemode_powerprofile_options.h"
#include "Log/logmessagewindow.h"
#include "RayCi/LiveMode_CrossSection.h"
#include "RayCi/LiveMode_Histogram.h"
#include "Single/single_2d_view.h"
#include "Single/snapshot.h"
#include "RayCi/LiveMode_Measurement.h"
#include "RayCi/LiveMode_Background.h"
#include "TimeSeries/time_series_view.h"
#include "RayCi/Time_Series.h"
#include "Stability/Beam/beam_stability_view.h"
#include "Common/histogram.h"
#include "Common/histogram_settings.h"
#include "LiveMode/LiveMode_Analysis.h"
#include "RayCi/Single_Measurement.h"
#include "RayCi/Beam_Stability.h"
#include "RayCi/Pointing_Stability.h"
#include "Stability/Pointing/pointing_stability_view.h"
#include "RayCi/Divergence.h"
#include "Divergence/divergence_view.h"
#include "RayCi/Beam_Line.h"
#include "BeamLine/beam_line_view.h"
#include "Rayci/Beam_Quality.h"
#include "BeamQuality/beam_quality_view.h"
#include "BeamQuality/Beam_Quality_LaserWavelngth_View.h"
#include "Single/snapshot_2d_view_settings.h"
#include "Single/single_2d_view_settings.h"
#include "TimeSeries/timeseries_2d_view_settings.h"
#include "Divergence/divergence_2d_view_settings.h"
#include "BeamLine/beamline_2d_view_settings.h"
#include "BeamQuality/beamquality_2d_view_settings.h"
#include "Single/snapshot_powerprofile_options.h"
#include <QFuture>
#include <QList>
#include <windows.h>
#include <psapi.h>

QT_BEGIN_NAMESPACE
namespace Ui { class RayCiMainWindow; }
QT_END_NAMESPACE

class LiveMode;
class LiveMode_Options;
class LiveMode_2D_View;
class BeamResults;
class PowerProfile;
class BeamProfilerDynamic;
class ThreeD_View;

class RayCiMainWindow : public QMainWindow {
    Q_OBJECT

signals:

private slots:
    void actionSingleMeasurement_Click() const;
    void actTimeSeries_Click() const;
    void actDivergence_Click() const;
    void actionBeamQuality_Click() ;
    void actionBeamLine_Click() const;
    void actionBeamStability_Click() const;
    void actionPointingStability_Click() const;
    void actionSnapshot_Click() const;
    void actConnectLiveMode_Click();
    void actOpenFile_Click();
    void actSaveData_Click();
    void actGlobal_Setting_Click();
    void actAbout_Click();
    void onCropToAOI();
    void onBinning2x2();
    void onSaveBeamQuality();
    void onSaveBeamQualityAs();
    void showMemoryInfo();

    void setTimeSeriesFramesSpan(int frames) const;
    void setTimeSeriesTimeSpan(double dTime) const;
    void onGetBeamStabilityData(const BeamStabilityDataBatch& data);
    void onGetBeamLineData(const BeamLineDataBatch& data);
    void onGetBeamQualityData();
    void onGetPointingStabilityData(const PointingStabilityDataBatch& data);
    void startRayCi() const;
    void stopRayCi() const;

public:
    explicit RayCiMainWindow(QWidget *parent = nullptr);
    ~RayCiMainWindow() override;
    void mainAOIChanged(int index) const;
    void Show_Or_Hide_Aoi(int index,bool show) const;
    void showBeamResult() const;
    void showCrossSection() const;
    void showCentroidDistances() const;
    void showPowerProfile() const;
    void showHistogram() const;
    void showBeamProfilerDynamic() const;
    void show3D_View();
    void show2DViewSetting();
    void showSnapShot2DViewSetting();
    void showSingle2DViewSetting();
    void showTimeSeries2DViewSetting();
    void showDivergence2DViewSetting();
    void showBeamLine2DViewSettings();
    void showBeamQuality2DViewSettings();
    static int findExposureTimeIndex(const std::vector<double>& _vecExposureTimes, double exposureTime);
    void changePowerProfileUnit();
    template<typename T>
    static QList<double> convertVectorToQList(const std::vector<T>& vec) {
        QList<double> result;
        for (const auto& val : vec) {
            result.append(static_cast<double>(val));
        }
        return result;
    }

    // AOI椭圆实时更新所需的getter方法
    LiveMode* getLiveMode() const { return liveMode; }
    LiveMode_Options* getLiveModeOptions() const { return liveModeOptions; }


private:
    Ui::RayCiMainWindow *ui;
    QProcess *rayCiProcess;

    // LiveMode
    LiveMode *liveMode = nullptr;
    LiveMode_Measurement *liveModeMeasurement = nullptr;
    LiveMode_Analysis *liveModeAnalysis = nullptr;
    LiveMode_Background *liveModeBackground = nullptr;
    LiveMode_Options *liveModeOptions = nullptr;
    LiveMode_2D_View_Settings *liveMode2DViewSettings = nullptr;
    LiveMode_2D_View *liveMode2DView = nullptr;


    // PowerProfile
    LiveMode_PowerProfiles *liveModePowerProfile = nullptr;
    PowerProfile *powerProfile = nullptr;
    LiveMode_PowerProfile_Options *liveModePowerProfileOptions = nullptr;

    // CrossSection
    LiveMode_CrossSection *liveModeCrossSection = nullptr;
    CrossSection *crossSection = nullptr;
    LiveMode_CrossSection_Options *liveModeCrossSectionOptions = nullptr;

    // Histogram
    LiveMode_Histogram *liveModeHistogram = nullptr;
    Histogram *histogram = nullptr;
    Histogram_Settings *histogramSettings = nullptr;

    // Results
    BeamResults *beamResults = nullptr;

    // CentroidDistances
    CentroidDistances *centroidDistances = nullptr;

    // BeamProfilerDynamic
    BeamProfilerDynamic *beamProfilerDynamic = nullptr;

    // 3DView
    ThreeD_View *threeDView = nullptr;

    // SnapShot
    SnapShot *snapShot = nullptr;
    SnapShot_2D_View_Settings *snapShot2DViewSettings = nullptr;
    Single_PowerProfile *snapshotPowerProfile = nullptr;
    SnapShot_PowerProfile_Options *snapshotPowerProfileOptions = nullptr;

    // Single
    Single_Measurement *singleMeasurement = nullptr;
    Single_2D_View *single2DView = nullptr;
    Single_2D_View_Settings *single2DViewSettings = nullptr;

    // TimeSeries
    Time_Series *timeSeries = nullptr;
    Time_Series_View *timeSeriesView = nullptr;
    TimeSeries_2D_View_Settings *timeSeries2DViewSettings = nullptr;

    // BeamStability
    Beam_Stability *beamStability = nullptr;
    Beam_Stability_View *beamStabilityView = nullptr;

    // PointingStability
    Pointing_Stability *pointingStability = nullptr;
    Pointing_Stability_View *pointingStabilityView = nullptr;

    // Divergence
    Divergence *divergence = nullptr;
    Divergence_View *divergenceView = nullptr;
    Divergence_2D_View_Settings *divergence2DViewSettings = nullptr;

    // BeamLine
    Beam_Line *beamLine = nullptr;
    Beam_Line_View *beamLineView = nullptr;
    BeamLine_2D_View_Settings *beamLine2DViewSettings = nullptr;

    // BeamQuality
    Beam_Quality *beamQuality = nullptr;
    Beam_Quality_View *beamQualityView = nullptr;
    Beam_Quality_Laser_Wavelength_View *beamQualityLaserWavelengthView = nullptr;
    BeamQuality_2D_View_Settings *beamQuality2DViewSettings = nullptr;
    int BeamQualityCurrentIndex=0;

    // Log
    LogMessageWindow *logMessageWindow = nullptr;

    bool _3D_Existed = false;
    QString unit;
    std::thread m_backgroundWorkerThread;
    static int divergenceIndex;
    static int beamLineIndex;
    static int beamQualityIndex;

    // 当前电机位置（外部坐标/光路位置）
    double m_currentMotorPosition = 0.0;

    // BeamQuality
    bool m_manualBqMeasurePending = false;
    double m_manualBqTargetPosition = 0.0;

    // 异步任务管理
    QFuture<void> m_beamQualityMeasurementTask;
    QList<double> m_bqPositionQueue;
    int m_currentPositionIndex = 0;
    bool m_bqSequentialMeasuring = false;
    bool m_isBqMeasurementRunning = false;

    static double unitConversion(const QString& unit);
    void hideLiveModeMenu() const;
    void showLiveModeMenu() const;
    void hideMeasurementMenu() const;
    void showMeasurementMenu() const;
    void clearBeamLineChart();
    void clearBeamQualityChart();
    void initSize();
    void initEllipses();
    void initImage();

    // BeamQuality位置指示器
    void updateBeamQualityPositionIndicator(double position);
    void setupBeamQualityChartAxes();
    void updateBeamQualityUI(const Beam_Quality &beamQuality);

private:
    void startSinglePositionMeasurement(double position);
    void processNextPosition();

    bool isMotorLim(double nextPos);
    void handleAutoScanCompleted(bool success);

private:
    void initUI();
    QList<QDockWidget*> getAllChildWindows() const;
    void arrangeAllChildWindows();
    void restoreVisibleWindows();
    std::unordered_map<QWidget*, QRect> visibleWindowStates;
    void closeEvent(QCloseEvent *event) override;

    static QString formatSize(qint64 bytes); // 转换字节数为合适单位（KB / MB / GB）
};


#endif //RAYCI_RAYCIMAINWINDOW_H
